package resultx

import (
	"app-api/common/xerr"
	"context"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	zerror "github.com/zeromicro/x/errors"
	"google.golang.org/grpc/status"
	"net/http"
)

type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func Success(data interface{}) *Response {
	code := xerr.OK
	return &Response{Code: code, Msg: xerr.CodeMap[code], Data: data}
}

func Fail(code int, err string) *Response {
	return &Response{Code: code, Msg: err, Data: nil}
}

func OkHandler(_ context.Context, v interface{}) any {
	return Success(v)
}

func ErrHandler(name string) func(ctx context.Context, err error) (int, any) {
	return func(ctx context.Context, err error) (int, any) {
		code := xerr.SystemError
		message := xerr.CodeMap[code]

		causeErr := errors.Cause(err)
		var e *zerror.CodeMsg
		if errors.As(causeErr, &e) {
			code, message = e.Code, e.Msg
		} else {
			if s, ok := status.FromError(causeErr); ok {
				code, message = int(s.Code()), s.Message()
			}
		}
		logx.WithContext(ctx).Errorf("【%s】err %v", name, err)
		return http.StatusInternalServerError, Fail(code, message)
	}
}
